package com.superlz.demo.security.web.controller;

import com.fasterxml.jackson.annotation.JsonView;
import com.superlz.demo.security.dto.User;
import com.superlz.demo.security.exception.UserNotExistException;
import com.superlz.demo.security.query.UserQuery;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import sun.plugin.liveconnect.SecurityContextHelper;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * lz试: 同一请求mapping路径和method，不能根据参数不同进行路由映射，会报IllegalStateException：Ambiguous mapping
 *
 * @RestController：对象自动json转换（参数和返回值）:参数只对get请求url的参数解析
 *
 * @Author: lz
 * @Description:
 * @Date: 2019/6/27
 */
@RestController
@RequestMapping("/user")
public class UserController {

    /*@GetMapping("/me")
    public Object getCurrnetUser (Authentication authentication) {
        //return authentication;
        return SecurityContextHolder.getContext().getAuthentication();
    }*/

    @GetMapping("/me")
    public Object getCurrnetUser (@AuthenticationPrincipal UserDetails userDetails) {
        return userDetails;
    }

    @GetMapping("/single")
    public List<User> query(@RequestParam(required = false, name = "username", defaultValue = "yoyo ") String username) {
        List<User> users = new ArrayList<>();
        users.add(new User());
        users.add(new User());
        users.add(new User());
        return users;
    }

    /**
     * swagger:
     *  @ApiOperation：方法描述信息
     *
     *  @ApiModelProperty：方法参数对象上描述信息
     *
     *  @ApiParam：单一属性参数前描述信息
     * ----
     *
     * @RequestParam 注解:默认必填，默认映射对应参数字段
     */
    @ApiOperation(value = "用户查询服务")
    @GetMapping
    @JsonView(User.UserSimpleView.class)
    public List<User> query(UserQuery query, @PageableDefault(page = 1, size = 12, sort = "username,asc") Pageable pageable) {
        // 利用反射的toString工具
        System.out.println(ReflectionToStringBuilder.toString(query, ToStringStyle.MULTI_LINE_STYLE));

        // 注意Pageable为接口，无法直接实例化，因此无法使用反射的方式
        System.out.println(pageable.getPageSize());
        System.out.println(pageable.getPageNumber());
        System.out.println(pageable.getSort());

        List<User> users = new ArrayList<>();
        users.add(new User());
        users.add(new User());
        users.add(new User());
        return users;
    }

    /**
     * :\\d+ 为参数正则校验
     */
    @GetMapping("/{id:\\d+}")
    @JsonView(User.UserDetailView.class)
    public User getDetail(@PathVariable(name = "id", required = false) String id) {

        throw new UserNotExistException("自定义异常");

        /*User user = new User();
        user.setUsername("jojo");
        return user;*/
    }

    @PostMapping
    public User create(@RequestBody @Valid User user, BindingResult errors) {
        if (errors.hasErrors()) {
            errors.getAllErrors().stream().forEach(error -> System.out.println(error.getDefaultMessage()));
        }

        System.out.println(user.getId());
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
        System.out.println(user.getBirthday());
        user.setId("1");
        return user;
    }

    @PutMapping("/{id:\\d+}")
    public User update(@RequestBody @Valid User user, BindingResult errors) {
        if (errors.hasErrors()) {
            errors.getAllErrors().stream().forEach(error -> System.out.println(error.getDefaultMessage()));
        }

        System.out.println(user.getId());
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
        System.out.println(user.getBirthday());
        user.setId("1");
        return user;
    }

    @DeleteMapping("/{id:\\d+}")
    public void delete(@ApiParam(value = "用户主键") @PathVariable String id) {
        System.out.println(id);
    }
}
